# -*- coding: utf-8 -*-
class student (object):
    def __init__(self,name,score):
        self.name=name
        self.score=score
    def print_score(self):
        print('name:%s,age:%s' % (self.name,self.score) )

bob=student('dave',18)
bob.print_score()

#class student (object): 表示student继承与object
#__init__ 构造函数 第一个参数永远是self，表示创建的实例本身
#和普通的函数相比，在类中定义的函数只有一点不同，就是第一个参数永远是实例变量self，并且，调用时，不用传递该参数


#访问限制 使用__xxx 可以通过一个公有函数去访问
class stu2(object):

    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score

    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))

dave=stu2('dave',100)
print(dave.get_name())



#继承
class Animal(object):
    def run(self):
        print("animal can run...")
class Dog(Animal):
    def run(self):
        print("dog can run....")
animal=Animal()
animal.run()

#多态表现
animal1=Dog()
animal1.run()


#鸭子类型  不一定需要继承Animal才有多态  只要有run方法就可以指向Animal的引用
class Duck(object):
    def run(self):
        print("duck can run ...")



#获取对象的信息 反射？
print(type(123))
#基本类型判断
print(type(123)==int)
#引用类型判定需要借助types模块
import types
def fn():
    pass
print("是个函数类型吗？：",type(fn)==types.FunctionType)

#判断对象是否是某个类型 isinstance
print(isinstance("aaa",object))

#获得对象属性、所有方法
print(dir('abc'))

#getattr()、setattr()以及hasattr()，我们可以直接操作一个对象的状态
print("有__len__这个属性吗：？",hasattr("abc","__len__"))
print(getattr("abc",'__len__'))
#可以传入一个默认值

print(getattr("abc",'gg',"找不到gg"))


#实例属性 为类所有 相当于static为类所有 
class Stu(object):
    count=0
    def __init__(self,name,age):
        self.__name=name
        self.__age=age
        Stu.count+=1
stu1=Stu("bob",15)
stu2=Stu("dave",17)

print("学生数:",Stu.count)
#千万不要对实例属性和类属性使用相同的名字，因为相同名称的实例属性将屏蔽掉类属性，但是当你删除实例属性后，再使用相同的名称，访问到的将是类属性。
        




